using System;
using System.Collections.Generic;
using System.Text;
using LispLib;
using System.IO;

//using GeneticAlgorithm.CP1;
using System.Collections;

namespace GeneticAlgorithm
{
    class Program
    {
        static void Main(string[] args)
        {
            #region CP1
            //// CP 1
            //Problem<float[], float> problem = new Problem();
            //Selection<float[], float[]> selection =
            //  new Selection<float[], float[]>(.5f, 10, Crossover.A, Mutation.A);
            //FitnessFunction<float> fitness = Fitness.A;
            //Procedure<float[], float[], float> procedure = new Procedure<float[], float[], float>(
            //    problem, selection, fitness);
            //procedure.Run(new Population(10), CP1.Terminate<float[], float[]>.A, true);
            #endregion

            // CP 3
            CP3.Problem problem = new CP3.Problem();

            #region CP3 parse tree

            Selection<LispLib.Interpreter.Pair, LispLib.Interpreter.Pair, float[]> selection =
                new Selection<LispLib.Interpreter.Pair, LispLib.Interpreter.Pair, float[]>(
                .75f, .001f, 10, CP3.ParseTree.Crossover.A, CP3.ParseTree.Mutation.A);

            Procedure<LispLib.Interpreter.Pair, LispLib.Interpreter.Pair, float[]> procedure =
                new Procedure<LispLib.Interpreter.Pair, LispLib.Interpreter.Pair, float[]>(problem, selection, CP3.Fitness.A);

            procedure.Run(new CP3.ParseTree.Population(), CP1.Terminate<LispLib.Interpreter.Pair, LispLib.Interpreter.Pair>.A, true);

            #endregion

            #region CP3 Bit String

            //Selection<int[], LispLib.Interpreter.Pair, float[]> selection =
            //    new Selection<int[], LispLib.Interpreter.Pair, float[]>(
            //    .75f, .001f, 5, CP3.BitString.Crossover.A, CP3.BitString.Mutation.A);

            //Procedure<int[], LispLib.Interpreter.Pair, float[]> procedure =
            //    new Procedure<int[], LispLib.Interpreter.Pair, float[]>(problem, selection, CP3.Fitness.A);

            //procedure.Run(new CP3.BitString.Population(), CP1.Terminate<int[], LispLib.Interpreter.Pair>.A, true);
            
            #endregion


            #region Junk
            Interpreter i = new Interpreter();

            int pos = 0;
            string s1 = "(+ c (* a b))", s2 = "(- a b)", s3 = "(* a b)", s4 = "(/ a b)";
            //Interpreter.Pair a = Interpreter.ReadOneExpr(s1, ref pos, s1.Length) as Interpreter.Pair; pos = 0;
            Interpreter.Pair b = Interpreter.ReadOneExpr(s2, ref pos, s2.Length) as Interpreter.Pair; pos = 0;
            //Interpreter.Pair c = Interpreter.ReadOneExpr(s3, ref pos, s3.Length) as Interpreter.Pair; pos = 0;
            //Interpreter.Pair d = Interpreter.ReadOneExpr(s4, ref pos, s4.Length) as Interpreter.Pair;

            
            //Type t = b.car_.GetType();
            //t = b.cdr_.GetType();
            //Interpreter.Pair p = b.cdr_ as Interpreter.Pair;
            //t = p.car_.GetType();

            //Object o = i.Globals.Get(b.car_.ToString(), i.Globals);

            //i.Eval("(set (a 4))");

            //o = i.Globals.Get(p.car_.ToString(), i.Globals);

            //Interpreter.Pair test = new Interpreter.Pair();
            //Interpreter.Pair test2 = new Interpreter.Pair();
            //test2.car_ = 4;
            //test2.cdr_ = 
            //test.car_ = "+";
            //test.cdr_ = 

            //i.Eval("(println (cdr '(rose violet daisy)))");
            //i.Eval("(define ('y 4))");
            //i.Eval("(+ x y)");
           // Interpreter.Pair test = i.Eval("(println (+ 3 (/ 3 2)))");

            // TODO check interpreter accuracy using the following expression
            // (car '(one two three)) // return one
            // (cdr '(one two three)) // return (two three)
            // (car '((one two three) (four five six) (seven eight nine))) // return (one two three)
            // (cdr (cdr '(one two three))) // return (three)
            // (cons 'one '(two three)) // return (one two three)
            // (cons 'one ()) // return (one)

            //Interpreter.Pair a = i.Eval("'(foo (bar baz))") as Interpreter.Pair;
            //Interpreter.Pair b = i.Eval("'(foo (bar baq))") as Interpreter.Pair;
            //Console.WriteLine("(listz,listq): {0}", Interpreter.Collate(a, b));
            //object obj = i.Eval("1 \n \"foo\" \n () \n '() \n '(foo bar baz) \n (set ('foo (lambda (x y) (+ x y))))");
            //Console.WriteLine("{0}", obj); 
            //obj = i.Eval("(define ('x 3))"); 
            //obj = i.Eval("(println \"x = \" x)");
            //obj = i.Eval("(println \"foo(2,5) = \" (foo 2 5))");
            //obj = i.Eval("(println (map (lambda (x) (* x 1.1e1)) '(0 1 2 3.3)))");

            //i.Eval("(define ('y (car x)))");
            //i.Eval("(println y)");
            //i.Eval("(println (define ('z 3)))");

            //// wiki example
            //i.Eval("(println '(1 2 foo))");
            //i.Eval("(println '(1 2 (3 4)))");
            //i.Eval("(println (+ 1 2 3 4))");
            //i.Eval("(println (if () '(1 2 foo) '(3 4 bar)))");
            //i.Eval("(println ((lambda (arg) (+ arg 1)) 5))");
            #endregion
        }
    }
}
